"""
HTTP中间件管理器 - 统一管理和执行中间件链
支持请求/响应处理、异常处理、条件执行等
"""

import asyncio
import functools
import inspect
import time
from typing import (
    Callable, List, Optional, Any, Dict, Union, Type,
    Awaitable, Protocol, runtime_checkable
)
from dataclasses import dataclass, field
from enum import Enum
from abc import ABC, abstractmethod

from fastapi import Request, Response, HTTPException
from fastapi.responses import JSONResponse
from starlette.middleware.base import BaseHTTPMiddleware

from ..logging.manager import get_logger
from ..events.bus import Event, EventBus

class MiddlewarePhase(Enum):
    """中间件执行阶段"""
    BEFORE_REQUEST = "before_request"
    AFTER_REQUEST = "after_request" 
    ON_EXCEPTION = "on_exception"
    ON_RESPONSE = "on_response"

class MiddlewarePriority(Enum):
    """中间件优先级"""
    HIGHEST = 100
    HIGH = 75
    NORMAL = 50
    LOW = 25
    LOWEST = 0

@runtime_checkable
class IMiddleware(Protocol):
    """中间件接口"""
    
    async def process_request(self, request: Request) -> Optional[Response]:
        """处理请求 - 返回Response则中断链，返回None继续"""
        ...
    
    async def process_response(self, request: Request, response: Response) -> Response:
        """处理响应"""
        ...
    
    async def process_exception(self, request: Request, exc: Exception) -> Optional[Response]:
        """处理异常 - 返回Response则处理异常，返回None继续抛出"""
        ...

class BaseMiddleware(ABC):
    """基础中间件类"""
    
    def __init__(self, name: str = None):
        self.name = name or self.__class__.__name__
        self.logger = get_logger(f"middleware.{self.name}")
    
    async def process_request(self, request: Request) -> Optional[Response]:
        """处理请求前"""
        return None
    
    async def process_response(self, request: Request, response: Response) -> Response:
        """处理响应后"""
        return response
    
    async def process_exception(self, request: Request, exc: Exception) -> Optional[Response]:
        """处理异常"""
        return None
    
    def should_process(self, request: Request) -> bool:
        """判断是否应该处理此请求"""
        return True

@dataclass
class MiddlewareConfig:
    """中间件配置"""
    name: str
    middleware: Union[IMiddleware, BaseMiddleware]
    priority: MiddlewarePriority = MiddlewarePriority.NORMAL
    phases: List[MiddlewarePhase] = field(default_factory=lambda: list(MiddlewarePhase))
    conditions: Optional[Callable[[Request], bool]] = None
    enabled: bool = True
    tags: List[str] = field(default_factory=list)

class MiddlewareChain:
    """中间件执行链"""
    
    def __init__(self, middlewares: List[MiddlewareConfig]):
        self.middlewares = sorted(middlewares, key=lambda m: m.priority.value, reverse=True)
        self.logger = get_logger("middleware_chain")
    
    async def process_request(self, request: Request) -> Optional[Response]:
        """执行请求处理链"""
        for config in self.middlewares:
            if not config.enabled or MiddlewarePhase.BEFORE_REQUEST not in config.phases:
                continue
            
            if config.conditions and not config.conditions(request):
                continue
            
            if hasattr(config.middleware, 'should_process') and not config.middleware.should_process(request):
                continue
            
            try:
                response = await config.middleware.process_request(request)
                if response is not None:
                    self.logger.info(
                        f"Request intercepted by middleware: {config.name}",
                        path=request.url.path,
                        method=request.method
                    )
                    return response
            except Exception as e:
                self.logger.error(
                    f"Middleware {config.name} failed in process_request",
                    error=str(e),
                    exc_info=e
                )
                raise
        
        return None
    
    async def process_response(self, request: Request, response: Response) -> Response:
        """执行响应处理链"""
        # 反向执行响应处理
        for config in reversed(self.middlewares):
            if not config.enabled or MiddlewarePhase.AFTER_REQUEST not in config.phases:
                continue
            
            if config.conditions and not config.conditions(request):
                continue
            
            if hasattr(config.middleware, 'should_process') and not config.middleware.should_process(request):
                continue
            
            try:
                response = await config.middleware.process_response(request, response)
            except Exception as e:
                self.logger.error(
                    f"Middleware {config.name} failed in process_response",
                    error=str(e),
                    exc_info=e
                )
                # 响应处理失败不中断链
                continue
        
        return response
    
    async def process_exception(self, request: Request, exc: Exception) -> Optional[Response]:
        """执行异常处理链"""
        for config in self.middlewares:
            if not config.enabled or MiddlewarePhase.ON_EXCEPTION not in config.phases:
                continue
            
            if config.conditions and not config.conditions(request):
                continue
            
            try:
                response = await config.middleware.process_exception(request, exc)
                if response is not None:
                    self.logger.info(
                        f"Exception handled by middleware: {config.name}",
                        exception=str(exc),
                        path=request.url.path
                    )
                    return response
            except Exception as new_exc:
                self.logger.error(
                    f"Middleware {config.name} failed in process_exception",
                    error=str(new_exc),
                    original_error=str(exc),
                    exc_info=new_exc
                )
                continue
        
        return None

class MiddlewareManager:
    """中间件管理器"""
    
    def __init__(self, event_bus: EventBus = None):
        """
        初始化中间件管理器
        
        参数：
            event_bus: 事件总线实例。如果不提供，将不会发布中间件事件。
        """
        self._middlewares: Dict[str, MiddlewareConfig] = {}
        self._chains: Dict[str, MiddlewareChain] = {}
        self.logger = get_logger("middleware_manager")
        self.event_bus = event_bus
    
    def register(
        self,
        middleware: Union[IMiddleware, BaseMiddleware],
        name: str = None,
        priority: MiddlewarePriority = MiddlewarePriority.NORMAL,
        phases: List[MiddlewarePhase] = None,
        conditions: Optional[Callable[[Request], bool]] = None,
        tags: List[str] = None,
        chain: str = "default"
    ) -> str:
        """注册中间件"""
        if name is None:
            name = getattr(middleware, 'name', middleware.__class__.__name__)
        
        if phases is None:
            phases = list(MiddlewarePhase)
        
        config = MiddlewareConfig(
            name=name,
            middleware=middleware,
            priority=priority,
            phases=phases,
            conditions=conditions,
            tags=tags or []
        )
        
        middleware_id = f"{chain}:{name}"
        self._middlewares[middleware_id] = config
        
        # 重建链
        self._rebuild_chain(chain)
        
        self.logger.info(
            f"Registered middleware: {name}",
            priority=priority.name,
            phases=[p.value for p in phases],
            chain=chain
        )
        
        # 发布事件（如果有事件总线）
        if self.event_bus:
            self.event_bus.publish(Event(
                event_type="middleware.registered",
                data={
                    "name": name,
                    "priority": priority.name,
                    "phases": [p.value for p in phases],
                    "chain": chain
                }
            ))
        
        return middleware_id
    
    def unregister(self, middleware_id: str) -> bool:
        """注销中间件"""
        if middleware_id not in self._middlewares:
            return False
        
        config = self._middlewares[middleware_id]
        chain = middleware_id.split(":")[0]
        
        del self._middlewares[middleware_id]
        self._rebuild_chain(chain)
        
        self.logger.info(f"Unregistered middleware: {config.name}")
        
        # 发布事件（如果有事件总线）
        if self.event_bus:
            self.event_bus.publish(Event(
                event_type="middleware.unregistered",
                data={"name": config.name, "chain": chain}
            ))
        
        return True
    
    def enable(self, middleware_id: str) -> bool:
        """启用中间件"""
        if middleware_id not in self._middlewares:
            return False
        
        self._middlewares[middleware_id].enabled = True
        self._rebuild_chain(middleware_id.split(":")[0])
        
        return True
    
    def disable(self, middleware_id: str) -> bool:
        """禁用中间件"""
        if middleware_id not in self._middlewares:
            return False
        
        self._middlewares[middleware_id].enabled = False
        self._rebuild_chain(middleware_id.split(":")[0])
        
        return True
    
    def get_chain(self, chain_name: str = "default") -> Optional[MiddlewareChain]:
        """获取中间件链"""
        return self._chains.get(chain_name)
    
    def _rebuild_chain(self, chain_name: str):
        """重建中间件链"""
        middlewares = [
            config for mid_id, config in self._middlewares.items()
            if mid_id.startswith(f"{chain_name}:") and config.enabled
        ]
        
        self._chains[chain_name] = MiddlewareChain(middlewares)
        
        self.logger.debug(
            f"Rebuilt middleware chain: {chain_name}",
            middleware_count=len(middlewares)
        )
    
    def list_middlewares(self, chain: str = None) -> List[Dict[str, Any]]:
        """列出中间件"""
        middlewares = []
        
        for mid_id, config in self._middlewares.items():
            chain_name = mid_id.split(":")[0]
            
            if chain and chain_name != chain:
                continue
            
            middlewares.append({
                "id": mid_id,
                "name": config.name,
                "chain": chain_name,
                "priority": config.priority.name,
                "phases": [p.value for p in config.phases],
                "enabled": config.enabled,
                "tags": config.tags
            })
        
        return sorted(middlewares, key=lambda m: m["priority"])
    
    def find_by_tag(self, tag: str) -> List[str]:
        """按标签查找中间件"""
        return [
            mid_id for mid_id, config in self._middlewares.items()
            if tag in config.tags
        ]

class FastAPIMiddlewareAdapter(BaseHTTPMiddleware):
    """FastAPI中间件适配器"""
    
    def __init__(self, app, manager: MiddlewareManager, chain: str = "default"):
        super().__init__(app)
        self.manager = manager
        self.chain_name = chain
        self.logger = get_logger("middleware_adapter")
    
    async def dispatch(self, request: Request, call_next):
        """处理请求"""
        chain = self.manager.get_chain(self.chain_name)
        if not chain:
            return await call_next(request)
        
        try:
            # 执行请求前处理
            early_response = await chain.process_request(request)
            if early_response:
                return early_response
            
            # 执行原始请求
            response = await call_next(request)
            
            # 执行响应后处理
            response = await chain.process_response(request, response)
            
            return response
            
        except Exception as exc:
            # 执行异常处理
            error_response = await chain.process_exception(request, exc)
            if error_response:
                return error_response
            
            # 如果没有处理，继续抛出异常
            raise

# 🚫 全局中间件管理器已完全移除
# 所有代码必须使用依赖注入模式获取中间件管理器实例

def get_middleware_manager() -> MiddlewareManager:
    """
    ⚠️ 此函数已被移除，强制使用依赖注入模式
    
    迁移指南：
    1. 通过 RedFireContainer 获取中间件管理器：
       container = RedFireContainer.create_for_service("my_service", settings)
       middleware_manager = container.middleware_manager()
    
    2. 在服务构造函数中声明依赖：
       def __init__(self, middleware_manager: MiddlewareManager):
           self.middleware_manager = middleware_manager
    
    3. 在测试中创建独立实例：
       test_manager = MiddlewareManager(event_bus=test_event_bus)
    """
    raise RuntimeError(
        "❌ get_middleware_manager() has been removed to eliminate global state issues. "
        "Use dependency injection instead:\n"
        "  • Get from container: container.middleware_manager()\n"
        "  • Inject in constructor: def __init__(self, middleware_manager: MiddlewareManager)\n"
        "  • For tests: MiddlewareManager(event_bus=test_event_bus)\n"
        "See EVENT_BUS_MIGRATION_GUIDE.md for complete migration instructions."
    )

def middleware(
    name: str = None,
    priority: MiddlewarePriority = MiddlewarePriority.NORMAL,
    phases: List[MiddlewarePhase] = None,
    conditions: Optional[Callable[[Request], bool]] = None,
    tags: List[str] = None,
    chain: str = "default",
    middleware_manager: MiddlewareManager = None
):
    """
    中间件装饰器 - 现在支持依赖注入模式
    
    参数：
        middleware_manager: 可选的中间件管理器实例。如果提供，将自动注册到该管理器。
                          如果不提供，仅标记为中间件，需要手动注册。
    
    示例：
        # 依赖注入模式（推荐）
        @middleware("auth", middleware_manager=injected_manager)
        class AuthMiddleware(BaseMiddleware):
            pass
        
        # 手动注册模式
        @middleware("auth")  # 仅标记，不自动注册
        class AuthMiddleware(BaseMiddleware):
            pass
        
        # 在应用启动时注册
        register_decorated_middlewares(my_module, middleware_manager)
    """
    def decorator(cls):
        # 标记中间件配置
        cls._middleware_config = {
            'name': name,
            'priority': priority,
            'phases': phases,
            'conditions': conditions,
            'tags': tags,
            'chain': chain
        }
        
        # 如果提供了管理器，自动注册（依赖注入模式）
        if middleware_manager is not None:
            if inspect.isclass(cls):
                # 类装饰器 - 实例化并注册
                instance = cls()
                middleware_manager.register(
                    middleware=instance,
                    name=name,
                    priority=priority,
                    phases=phases,
                    conditions=conditions,
                    tags=tags,
                    chain=chain
                )
            else:
                # 函数装饰器 - 包装为中间件类
                class FunctionMiddleware(BaseMiddleware):
                    async def process_request(self, request: Request):
                        return await cls(request)
                
                middleware_manager.register(
                    middleware=FunctionMiddleware(),
                    name=name or cls.__name__,
                    priority=priority,
                    phases=phases or [MiddlewarePhase.BEFORE_REQUEST],
                    conditions=conditions,
                    tags=tags,
                    chain=chain
                )
        
        return cls
    
    return decorator

def register_decorated_middlewares(module, middleware_manager: MiddlewareManager):
    """
    注册模块中所有装饰器标记的中间件
    
    参数：
        module: 包含中间件的模块
        middleware_manager: 中间件管理器实例
    
    示例：
        # 在应用启动时注册所有中间件
        from my_app import middlewares
        register_decorated_middlewares(middlewares, container.middleware_manager())
    """
    import inspect
    
    for name, obj in inspect.getmembers(module):
        if hasattr(obj, '_middleware_config'):
            config = obj._middleware_config
            
            if inspect.isclass(obj):
                # 类中间件 - 实例化并注册
                instance = obj()
                middleware_manager.register(
                    middleware=instance,
                    name=config['name'],
                    priority=config['priority'],
                    phases=config['phases'],
                    conditions=config['conditions'],
                    tags=config['tags'],
                    chain=config['chain']
                )
            else:
                # 函数中间件 - 包装为中间件类
                class FunctionMiddleware(BaseMiddleware):
                    async def process_request(self, request: Request):
                        return await obj(request)
                
                middleware_manager.register(
                    middleware=FunctionMiddleware(),
                    name=config['name'] or obj.__name__,
                    priority=config['priority'],
                    phases=config['phases'] or [MiddlewarePhase.BEFORE_REQUEST],
                    conditions=config['conditions'],
                    tags=config['tags'],
                    chain=config['chain']
                )

# 示例中间件
if __name__ == "__main__":
    # 示例：CORS中间件
    class CORSMiddleware(BaseMiddleware):
        def __init__(self, allowed_origins: List[str] = None):
            super().__init__()
            self.allowed_origins = allowed_origins or ["*"]
        
        async def process_response(self, request: Request, response: Response) -> Response:
            origin = request.headers.get("origin")
            if origin and (self.allowed_origins == ["*"] or origin in self.allowed_origins):
                response.headers["Access-Control-Allow-Origin"] = origin
                response.headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, DELETE, OPTIONS"
                response.headers["Access-Control-Allow-Headers"] = "Content-Type, Authorization"
            return response
    
    # 示例：限流中间件
    @middleware(
        name="rate_limiter",
        priority=MiddlewarePriority.HIGH,
        phases=[MiddlewarePhase.BEFORE_REQUEST]
    )
    class RateLimitMiddleware(BaseMiddleware):
        def __init__(self):
            super().__init__()
            self.requests = {}  # 简单的内存存储
        
        async def process_request(self, request: Request) -> Optional[Response]:
            client_ip = request.client.host
            current_time = time.time()
            
            # 简单的限流逻辑
            if client_ip in self.requests:
                if current_time - self.requests[client_ip] < 1:  # 1秒限制
                    return JSONResponse(
                        status_code=429,
                        content={"error": "Rate limit exceeded"}
                    )
            
            self.requests[client_ip] = current_time
            return None
    
    # 使用示例
    manager = get_middleware_manager()
    
    # 注册CORS中间件
    cors = CORSMiddleware(["http://localhost:3000"])
    manager.register(
        cors,
        priority=MiddlewarePriority.LOW,
        phases=[MiddlewarePhase.AFTER_REQUEST]
    )
